package com.oristartech.netty.common.content;

import com.oristartech.netty.common.message.AbstractMessage;
import com.oristartech.netty.common.message.ResponseMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.time.Instant;
import java.util.Objects;

/**
 * ServiceMethodUtils
 *
 * @author: chenfenghai
 * @version: 1.0
 * @date: 2020-03-27 14:49
 * @blame Team
 */
@Slf4j
public class ServiceMethodUtils {

    /**
     ** 调用请求方法
     *
     * @param context ApplicationContext
     * @param message AbstractMessage
     * @return ResponseMessage
     */
    public static ResponseMessage invokeRequestMethod(ApplicationContext context, AbstractMessage message) {
        Objects.requireNonNull(context);
        Objects.requireNonNull(message);
        ResponseMessage responseMessage = ResponseMessage.builder()
                .id(message.getId())
                .tenantId(message.getTenantId())
                .cinemaCode(message.getCinemaCode())
                .timestamp(Instant.now().toEpochMilli())
                .build();
        try {
            // 请求内容
            RequestContent requestContent = new RequestContent(message.getContent());
            // 响应内容
            ResponseContent responseContent = new ResponseContent(
                    requestContent.getCmd(), requestContent.getUuid());
            // 服务bean对象
            Object serviceBean = context.getBean(message.getServiceName());
            // 服务方法
            Method serviceMethod = ReflectionUtils.findMethod(serviceBean.getClass(),
                    message.getMethodName(), RequestContent.class, ResponseContent.class);
            if (serviceMethod == null) {
                throw new RuntimeException("找不到方法：" + message.getServiceName()
                        + "." + message.getMethodName());
            }
            // 调用方法
            ReflectionUtils.invokeMethod(serviceMethod, serviceBean, requestContent, responseContent);
            // 设置返回结果
            responseMessage.setContent(responseContent.toJson());
        } catch (Exception ex) {
            log.error("", ex);
            responseMessage.setContent(ex.getMessage());
        }
        return responseMessage;
    }

    /**
     ** 调用通知方法
     *
     * @param context ApplicationContext
     * @param message AbstractMessage
     * @return ResponseMessage
     */
    public static void invokeNoticeMethod(ApplicationContext context, AbstractMessage message) {
        Objects.requireNonNull(context);
        Objects.requireNonNull(message);
        try {
            // 请求内容
            RequestContent requestContent = new RequestContent(message.getContent());
            // 服务bean对象
            Object serviceBean = context.getBean(message.getServiceName());
            // 服务方法
            Method serviceMethod = ReflectionUtils.findMethod(serviceBean.getClass(),
                    message.getMethodName(), RequestContent.class);
            if (serviceMethod == null) {
                throw new RuntimeException("找不到方法：" + message.getServiceName()
                        + "." + message.getMethodName());
            }
            // 调用方法
            ReflectionUtils.invokeMethod(serviceMethod, serviceBean, requestContent);
        } catch (Exception ex) {
            log.error("", ex);
        }
    }
}
